<?php
declare(strict_types=1);

namespace App\Controller\Admin;

use App\Annotation\ModuleAndAction;
use App\Helper\JwtHelper;
use App\Middleware\AdminMiddleware;
use App\Model\ContentItem;
use App\Model\ContentTag;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\Utils\ApplicationContext;
use Psr\Http\Message\ResponseInterface;
use stdClass;

/**
 * @AutoController()
 * @ModuleAndAction(module="管理后台:内容管理:内容管理", icon="fa fa-file-text")
 * @Middleware(AdminMiddleware::class)
 */
class ItemController extends BaseController
{
    public $model = ContentItem::class;

    /**
     * @ModuleAndAction(module="管理后台:内容管理:内容管理", action="查看列表")
     */
    public function getAllTypes(): ResponseInterface
    {
        return $this->response->json(static::genSuccessData(ContentItem::TYPE_NAMES));
    }

    /**
     * @ModuleAndAction(module="管理后台:内容管理:内容管理", action="查看列表")
     */
    public function getAllStatus(): ResponseInterface
    {
        return $this->response->json(static::genSuccessData(ContentItem::STATUS_NAMES));
    }

    /**
     * @ModuleAndAction(module="管理后台:内容管理:内容管理", action="锁定")
     */
    public function setLock(): ResponseInterface
    {
        $jwt = JwtHelper::decodeWithRequest(JwtHelper::ADMIN_JWT_TOKEN, $this->request);
        if (!$jwt || ($lockedBy = $jwt->data->id) <= 0) {
            return $this->response->json(static::genErrorData('请登录 !'));
        }
        $id = intval($this->request->post('id', 0));
        if ($id <= 0) {
            return $this->response->json(static::genErrorData('ID错误 !'));
        }
        $model = ApplicationContext::getContainer()->get($this->model);
        if (intval($this->request->post('lock', 0)) > 0) {
            $rowsCount = Db::connection($model->getConnectionName())
                ->table($model->getTable())
                ->where('id', '=', $id)
                ->where('main_id', '=', 0)
                ->where('locked_by', '=', 0)
                ->update(['locked_by' => $lockedBy]);
            return $this->response->json(static::genSuccessData(['rows_count' => $rowsCount]));
        }
        $rowsCount = Db::connection($model->getConnectionName())
            ->table($model->getTable())
            ->where('id', '=', $id)
            ->where('main_id', '=', 0)
            ->where('locked_by', '=', $lockedBy)
            ->update(['locked_by' => 0]);
        return $this->response->json(static::genSuccessData(['rows_count' => $rowsCount]));
    }

    /**
     * @ModuleAndAction(module="管理后台:内容管理:内容管理", action="查看详情")
     */
    public function getAllContentsById(): ResponseInterface
    {
        $id = $this->request->query('id', 0);
        $id = intval($id);
        if ($id <= 0) {
            return $this->response->json(static::genErrorData());
        }
        $models = ContentItem::query()
            ->where('id', '=', $id)
            ->orWhere('main_id', '=', $id)
            ->orderBy('page_number')
            ->orderBy('created_at')
            ->getModels();
        $newOne = new stdClass();
        $newOne->id = 0;
        $newOne->page_number = 1;
        $newOne->main_id = $id;
        array_push($models, $newOne);
        return $this->response->json(static::genSuccessData($models, count($models) - 1));
    }

    protected function fixListData(?array $data): ?array
    {
        is_array($data) || $data = [];
        /* @var stdClass $item */
        foreach ($data as $i => $item) {
            $data[$i]->title = (empty($data[$i]->title) ? '未填写标题' : $data[$i]->title);
            $data[$i]->type_name = ContentItem::getTypeName($item->type_id);
            $data[$i]->menu_name = ContentItem::getMenuName($item->menu_id);
            $lockedByAdmin = ContentItem::getLockedByAdmin($item->locked_by);
            $data[$i]->locked_by_admin = $lockedByAdmin;
            empty($lockedByAdmin) && $data[$i]->locked_by = 0;
        }
        return $data;
    }

    protected function fixPostData(?array $data): ?array
    {
        is_null($data) && $data = $this->request->post();
        is_array($data) || $data = [];
        if (key_exists('enable_start', $data) && $data['enable_start'] == '') {
            $data['enable_start'] = null;
        }
        if (key_exists('enable_end', $data) && $data['enable_end'] == '') {
            $data['enable_end'] = null;
        }
        if (key_exists('tag_names', $data)) {
            $tagIds = ContentTag::getIdsByNames($data['tag_names']);
            $data['tag_ids'] = implode(',', $tagIds);
            unset($data['tag_names']);
        }
        return $data;
    }

    protected function fixInfoData(?stdClass $data): ?stdClass
    {
        if (!$data) {
            return null;
        }
        $tagIds = ($data->tag_ids ?? null);
        if ($tagIds) {
            $data->tag_names = ContentTag::getNamesByIds($tagIds);
        }
        $data->locked_by_admin = ContentItem::getLockedByAdmin($data->locked_by);
        return $data;
    }

    protected function beforeDeleteModelCache(?array $ids): void
    {
        if (!$ids) {
            return;
        }
        $models = ContentItem::findManyFromCache($ids);
        /* @var ContentItem $model */
        foreach ($models as $model) {
            if ($model->viewed_count == 0 && $model->liked_count == 0) {
                continue;
            }
            ContentItem::query()
                ->where('id', '=', $model->id)
                ->update([
                    'viewed_count' => $model->viewed_count,
                    'liked_count' => $model->liked_count,
                ]);
        }
    }
}
